
package com.cgmnx.admin.common.idgenerator;

import com.google.common.base.Strings;
import com.google.common.collect.Lists;

import java.sql.Timestamp;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.atomic.AtomicLong;


/**
 *
 */
public class DefaultIdentityGenerator implements IdentityGenerator {

    private static final int[] TIME_INDEX = new int[]{2, 3, 5, 6, 8, 9};
    private static final short[][] SHUFFLE_DATA = new short[4][10];
    private static final int EMPTY_SUFFIX = -1;
    private static final char ZERO = '0';
    private static final int DEFAULT_RANDOM_LENGTH = 10;
    private static final int MAX_OFFSET_LENGTH = 4;
    private static final int MIN_OFFSET_LENGTH = 2;
    private static AtomicLong idGenerator = new AtomicLong(0);
    private final SystemCodeType sysCode;
    private final int suffixLength;

    public DefaultIdentityGenerator(SystemCodeType sysCode, int suffixLength) {
        this.sysCode = sysCode;
        this.suffixLength = suffixLength;
        initData();
    }

    private void initData() {
        List<Short> data = Lists.newArrayListWithExpectedSize(100);
        for (short i = 0; i < 10; i++) {
            data.add(i);
        }
        for (int i = 0; i < 4; i++) {
            Collections.shuffle(data);
            toArray(data, SHUFFLE_DATA[i]);
        }
    }

    private short[] toArray(List<Short> shortList, short[] data) {
        int len = shortList.size();
        for (int i = 0; i < len; i++) {
            data[i] = shortList.get(i);
        }
        return data;
    }

    @Override
    public String generateOrderIdStr() {
        return sysCode.getDesc() + generateOrderId();
    }

    /**
     * 2为syscode + 6为日期 + 10位数字
     *
     * @return
     */
    @Override
    public long generateOrderId() {
        return generateOrderId(EMPTY_SUFFIX);
    }


    @Override
    public long generateOrderId(int suffix) {
        // 构建系统编号
        StringBuilder builder = new StringBuilder();
        // 当前时间戳2016-11-07 22:26:14.143
        String tsString = new Timestamp(System.currentTimeMillis()).toString();

        // 后缀长度
        int suffixLength = suffix == EMPTY_SUFFIX ? 0 : this.suffixLength;

        // 如果后缀长度大于 4-2 取 2 否则取 4-后缀长度
        int restOffsetNum = suffixLength > MAX_OFFSET_LENGTH - MIN_OFFSET_LENGTH ? MIN_OFFSET_LENGTH : MAX_OFFSET_LENGTH - suffixLength;
        int randomLength;
        if (suffixLength < 4) {
            for (int index : TIME_INDEX) {
                builder.append(tsString.charAt(index));
            }
            randomLength = DEFAULT_RANDOM_LENGTH - suffixLength;
        } else {
            randomLength = DEFAULT_RANDOM_LENGTH + TIME_INDEX.length - suffixLength;
        }
        int timeLength = randomLength - restOffsetNum;

        String ts = String.valueOf(System.currentTimeMillis());
        // suffix先占用随机数的位置，再占用ts的位置，随机数最多占用2位，ts最多占用4位(已在上层规定了suffixLength <= 6)
        for (int i = ts.length() - timeLength; i < ts.length(); i++) {
            builder.append(ts.charAt(i));
        }

        return Long.valueOf(builder
                .append(getRestOffset(restOffsetNum, Integer.parseInt(ts.charAt(ts.length() - 1) + "")))
                .append(fixSize(suffix, suffixLength)).toString());
    }

    @Override
    public int getSuffix(long orderId) {
        throw new UnsupportedOperationException();
    }

    private String getRestOffset(int offsetNum, int delta) {
        StringBuilder builder = new StringBuilder();
        long index = idGenerator.getAndIncrement() + delta;
        for (int i = 0; i < offsetNum; i++) {
            builder.append(SHUFFLE_DATA[i][(int) (index % 10)]);
            index = index / 10;
        }
        return builder.toString();
    }

    private String fixSize(int num, int numSize) {
        return numSize == 0 ? "" : Strings.padStart(String.valueOf(num), numSize, ZERO);
    }
}